#ifndef PARSER_HPP

#define PARSER_HPP

#include "lexer.hpp"

class Node;
class VarNode;
class ListNode;
class Type;
class TypeArgs;

class Parser {
private:
    Lexer* _lex;
    Token* _cur_token;

public:
    Parser(Lexer* lex);
    void eval();

    void consume();
    Token* get_token();
    //void unget_token(Token* t);
    
    Node* statement();
    Node* statements(ListNode* nodelist);
    Node* simple_stmt();
    Node* if_stmt();
    Node* declare_stmt();
    Node* typedef_stmt();
    Node* if_expr(Node* left);
    Node* test(Node* left);
    Node* trails(Node* left);
    Node* lambda_def();

    Node* suite();

    Node* expression();
    Node* or_test();
    Node* and_test();
    Node* not_test();
    Node* comparison();
    Node* or_expr();
    Node* xor_expr();
    Node* and_expr();
    Node* shift_expr();
    Node* arith_expr();
    Node* term();
    Node* factor();
    Node* atom();

    Type* type_stmt();
    Type* type_atom();
    TypeArgs* tp_args();
    TypeArgs* type_trailer();
    
    void match(Token* t, TokenType tt);

    int stoi(Token* data);
};

void eval(BufferedInputStream* steam);

#endif
